import json

class Student:
    def __init__(self, username, fullName, age, school, interests, relations):
        self.username = username
        self.fullName = fullName
        self.age = age
        self.school = school
        self.interests = interests
        self.relations = relations

class SocialNetwork:
    class HashTable:
        def __init__(self, students_data):
            # 获取Student类构造函数的有效参数
            valid_params = Student.__init__.__code__.co_varnames[1:]  # 排除self参数
            # 过滤掉无效的字段
            self.students = {
                student['username']: Student(**{k: v for k, v in student.items() if k in valid_params})
                for student in students_data
            }
            self.adjacency_list = {}
            # 初始化邻接表
            for student in self.students.values():
                self.adjacency_list[student.username] = []

        def get_friends(self, username):
            if username not in self.students:
                return f"Student {username} not found."
            student = self.students[username]
            friends = [self.students[friend].fullName for friend in student.relations]
            return friends

        def add_friend(self, username, new_friend_username):
            if username not in self.students or new_friend_username not in self.students:
                return "One of the usernames provided is invalid."
            if new_friend_username in self.students[username].relations:
                return f"{new_friend_username} is already a friend of {username}."
            
            self.students[username].relations.append(new_friend_username)
            self.students[new_friend_username].relations.append(username)
            return f"Friend added successfully."

        def filter_by_interest(self, interest):
            filtered_students = [student.fullName for student in self.students.values() if interest in student.interests]
            return filtered_students

        def define_communities(self):
            # 创建基于兴趣的社群字典
            interest_communities = {}
            
            for student in self.students.values():
                for interest in student.interests:
                    if interest not in interest_communities:
                        interest_communities[interest] = []
                    interest_communities[interest].append(student.username)
            
            # 返回包含兴趣名称的元组列表
            return list(interest_communities.items())  # 修改为返回（兴趣，用户列表）的元组

        def find_bridges(self):
            communities = self.define_communities()
            bridge_pairs = []

            for i in range(len(communities)):
                for j in range(i + 1, len(communities)):
                    interest1, members1 = communities[i]
                    interest2, members2 = communities[j]
                    common = set(members1).intersection(members2)
                    
                    if common:
                        bridge_pairs.append({
                            "communities": (interest1, interest2),
                            "bridges": list(common)
                        })
            
            return bridge_pairs

    def find_bridges(self):
        visited = set()
        bridges = []

        def dfs(node, parent, discovery_time, low, time):
            nonlocal bridges
            visited.add(node)
            discovery_time[node] = time[0]
            low[node] = time[0]
            time[0] += 1

            for neighbor in self.adjacency_list.get(node, []):
                if neighbor not in visited:
                    dfs(neighbor, node, discovery_time, low, time)
                    low[node] = min(low[node], low[neighbor])
                    if low[neighbor] > discovery_time[node]:
                        bridges.append((node, neighbor))
                elif neighbor != parent:
                    low[node] = min(low[node], discovery_time[neighbor])

        discovery_time = {}
        low = {}
        time = [0]
        for node in self.adjacency_list:
            if node not in visited:
                dfs(node, -1, discovery_time, low, time)

        return bridges

def main():
    with open('.\\ressources\\students.json', 'r') as file:
        data = json.load(file)
    
    social_network = SocialNetwork(data['students'])

    while True:
        print("\nUniversity Social Network System")
        print("1. Get Friends")
        print("2. Add Friend")
        print("3. Filter by Interest")
        print("4. Define Communities")
        print("5. Find Bridges")
        print("6. Exit")

        choice = input("Enter your choice: ")

        if choice == '1':
            username = input("Enter the username: ")
            print(social_network.get_friends(username))
        elif choice == '2':
            username = input("Enter your username: ")
            new_friend_username = input("Enter the new friend's username: ")
            print(social_network.add_friend(username, new_friend_username))
        elif choice == '3':
            interest = input("Enter the interest to filter by: ")
            print(social_network.filter_by_interest(interest))
        elif choice == '4':
            communities = social_network.define_communities()
            for idx, (interest, members) in enumerate(communities, start=1):  # 解包元组
                print(f"Community {idx} [Interest: {interest}]: {members}")  # 添加兴趣显示
        elif choice == '5':
            bridges = social_network.find_bridges()
            print("\nBridges between communities:")
            for pair in bridges:
                comm1, comm2 = pair["communities"]
                print(f"{comm1} <-> {comm2}: {pair['bridges']}")
        elif choice == '6':
            break
        else:
            print("Invalid choice. Please try again.")

if __name__ == "__main__":
    main()



